import base64
import json
from datetime import datetime
import random
import requests

from src.Business.wechat.WxPayV3.WxPayApi import WxPayApi
from src.Business.wechat.WxPayV3.WxPayTool import WxPayTool


class PayAgent:
    appid = "wx82fcb5c79c5943c5"  # 小程序id
    mchid = "1664546599"  # 商户id
    serial_no = "77FE40E4735D85ECA2BC94AA983620E7281720FA"  # 证书序列号
    secret = "72347ac4a69093ddefc05de2c4910f34"  # 证书密钥

    def __init__(self):
        wx_info = {
            "mchid": self.mchid,  # 商户id
            "serial_no": self.serial_no,  # 证书编号
            "secret": self.secret,  # 证书密钥
        }
        self.wx = WxPayApi(**wx_info)
        self.pay_tool = WxPayTool(**wx_info)

    def pay(self, **kwargs):
        """
        支付
        :param kwargs:
        :return:
        """
        payload = self.make_transactions_data(**kwargs)
        perpay_info, timestamp_str, nonce_str = self.wx.pay_transactions(post_data=payload)
        result = self.pay_tool.make_mini_pay_info(appId=self.appid, prepay_id=perpay_info["prepay_id"],
                                                  timestamp=timestamp_str, nonceStr=nonce_str)
        return result

    def refund(self, **kwargs):
        """
        退款
        """
        out_trade_no = kwargs.get("out_trade_no")  # 退款订单号
        reason = kwargs.get("reason")  # 退款理由
        total = kwargs.get("total")  # 订单总金额
        refund = kwargs.get("refund")  # 退款金额
        if refund < 1:
            return {
                "status": "退款成功"
            }
        refund_info = {
            "out_trade_no": out_trade_no,  # 订单编号
            "out_refund_no": self.wx.wx.get_random_str(),  # 退款订单号
            "reason": reason,  # 退款理由
            "amount": {
                "refund": refund,
                "total": total,
                "currency": "CNY"
            },  # 退款金额
        }
        result, timestamp_str, nonce_str = self.wx.refunds(post_data=refund_info)
        return result

    def flush_certificates(self):
        """
        刷新平台证书
        """
        certificates = self.wx.get_certificates()
        certificate = certificates["data"][0]
        serial_no = certificate.get("serial_no")
        encrypt_certificate = certificate.get("encrypt_certificate")
        associated_data = encrypt_certificate.get("associated_data")
        ciphertext = encrypt_certificate.get("ciphertext")
        nonce = encrypt_certificate.get("nonce")
        result = self.wx.wx.decrypt_to_str(associated_data=associated_data, ciphertext=ciphertext, nonce=nonce)
        with open(f"{serial_no}.pem", "w") as f:
            f.write(result)
        return (serial_no, result)

    def verify_signer(self, **kwargs):
        """
        验证平台签名
        """
        signature = kwargs.get("signature")
        timestamp_str = kwargs.get("timestamp_str")
        nonce = kwargs.get("nonce")
        serial = kwargs.get("serial")
        result = self.wx.wx.verify_signature(**kwargs)
        print(result)

    def get_transctions_pay_starus(self, **kwargs):
        """
        获取支付状态
        """
        out_trade_no = kwargs.get("out_trade_no")
        result, timestamp, noce_str = self.wx.transactions_select(out_trade_no=out_trade_no, mchid=self.mchid)
        return result

    def make_transactions_data(self, **kwargs):
        """
        生成下单请求体
        :param kwargs:
        :return:
        """
        description = kwargs.get("description")
        out_trade_no = kwargs.get("out_trade_no")
        amount = kwargs.get("amount")
        code = kwargs.get("code")
        payload = {
            "appid": self.appid,
            "mchid": self.mchid,
            "description": description,
            "out_trade_no": out_trade_no,
            "notify_url": "https://www.unicorn-go.com/order/paySuccess",
            "amount": {
                "total": amount,
                "currency": "CNY"
            },
            "payer": {"openid": self.get_openid(code)},
        }
        return payload

    def get_openid(self, code):
        """
        获取openid
        :param code:
        :return:
        """
        info = {
            "appid": self.appid,
            "secret": self.secret,
            "js_code": code,
            "grant_type": "authorization_code"
        }
        response = requests.get(url='https://api.weixin.qq.com/sns/jscode2session', params=info)
        result = response.json()
        if "openid" in result.keys():
            openid = result['openid']
            return openid
        else:
            raise ValueError(result.get("errmsg"))

    def get_transactions_data(self):
        """
        下单请求体
        :return:
        """
        return {
            "appid": self.appid,
            "mchid": self.mchid,
            "description": "1",
            "out_trade_no": self.order_num(),
            "notify_url": "https://pay.weixin.qq.com/index.php/core/account/info",
            "amount": {
                "total": 1,
                "currency": "CNY"
            },
            "payer": {"openid": "op8KL61VPjccXboe5b1VSBmawqQc"},
        }

    def get_open_id(self, **kwargs):
        """
        获取open_id
        :param kwargs:
        :return:
        """
        info = {

        }

    @staticmethod
    def order_num():
        """
        获取随机订单号
        :return:
        """
        now = datetime.now()
        result = str(now.year) + str(now.month) + str(now.day) + str(now.microsecond) + str(
            random.randrange(10000000, 99999999))
        return result


if __name__ == '__main__':
    agent = PayAgent()
    post_data = {
        "id": "8bb6a4fa-aa71-5dfc-afd4-89d9d42f1933",
        "create_time": "2024-01-07T09:16:47+08:00",
        "resource_type": "encrypt-resource",
        "event_type": "TRANSACTION.SUCCESS",
        "summary": "支付成功",
        "resource": {
            "original_type": "transaction",
            "algorithm": "AEAD_AES_256_GCM",
            "ciphertext": "IJYVqSklnIwFePfxlVC1h2ForjDES0uUkoVkOmnuinhkCZxLDEqr7/jZtuHJVDtLuyU1IHOPZlm7yOAguUeB3D7E6H35BwnODjA9yMTJpCKdUDIUtLx0rmF6YWc/PgBi+apQZbSq3oMIP4f1zD5S6HFtU9CMCXYkRjy9vn15++IYSkpCxlsdz7zB/c3MTEdqhDdXBA3MGEqwABVcLG/ggLQQ66VPpgNQFyEO/2xYNEPVht/C2cLGODhmg6O3KzONWltOSICUrkb/L6ouSlVeL9MT/ioDn+HtTE+JcWOTg8qgOWzoSK2lScRFRMROK7XSAjyAtcDd0++QLverrCCY/rnV2fDyfZR+iaI3KS9f+K3Z26/OgaheRwbf8QbIXr8WakDGNT4h152jHTxsPmik7K/Rysu2zktqipo5KGZTY5nfWFpvKLNV95XHh/e0YZWSRMplLHDn/rLIyZbASRrlMhEFwd9aeRvP9HrjI5LbUB8xTOHgq1U6tpY/OnICjk2ePRXILBSMzchB5Q+yx3XDtbLPRtzjhLlx4INmVL0PiQQdRF0tJaoO5CG/MoBxU1Z8JvwNvvJHev/fte89u/u1",
            "associated_data": "transaction",
            "nonce": "3vrTl0exs3Z5"
        }
    }
    info = {
        "signature": "FnwNLRqlstH7X8SeTg/bkyfezIxGpaLAZxg1eQC7lkg+njqV2yqTiil7sNYxBeNXQnbrF5k0MWW06AB1hEZFkOs3P9CBCebvwwxeFaIYR6i3j1F2pgPgMIqHELVlHKE1xVwehMEz0zbbVH50Fam/Ydop+d7n5Huay8BjKo+iGSe/FFy3oVY38vu2vRFDLybrzcWYyg30bBtfSqtLr6TSLlhBKEN6nIHHk+zNql2q3PzRpr4Fp+8gCPrra+n1u7HsePK0PHgggNZ7eZ/vqQN9UtvNni6dR7mEVKyiEzEeTTmmvZbbbnf9YeO2WMDD/c74Nzt5zn8AyWBPydqolXHEqg==",
        "serial": "7457B5978E1C9E00A5F2D7E558CF497B58E870B3",
        "post_data": json.dumps(post_data),
        "timestamp_str": "1704590207",
        "nonce": "akyFlMC3wVTZF0H374X8XlvySxeoxGVT"
    }
    result = agent.verify_signer(**info)
    print(result)
    # agent.pay(post_data=post_data)
